/// ****************************************************************************
/// Author:	        Robin Zhu
/// Create Date:	2011-11-1
/// Purpose: 		用于支持Linq语法的SQL查询定义的类和接口的文件
/// ****************************************************************************
/// Modify By		Date			Remark
/// ****************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;

namespace RB.DataAccess.Linq
{
    /// <summary>
    /// 支持Linq语法的SQL查询定义接口
    /// </summary>
    public interface ISqlQueryable
    {
        string QueryName { get; }

        Dictionary<string, string> QueryPropertyFieldMap { get; }
    }

    /// <summary>
    /// 支持Linq语法的SQL查询定义类
    /// </summary>
    /// <typeparam name="T">从关系表映射出的对象的类型</typeparam>
    public class SqlQueryable<T> : IOrderedQueryable<T>, ISqlQueryable
    {
        private SqlQueryableProvider _provider;
        private Expression _expression;

        private string _mappingTo;

        public SqlQueryable(SqlQueryableProvider provider)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            this._provider = provider;
            this._expression = Expression.Constant(this);
        }

        public SqlQueryable(SqlQueryableProvider provider, string mappingTo)
            : this(provider)
        {
            this._mappingTo = mappingTo;
        }

        public SqlQueryable(SqlQueryableProvider provider, Expression expression)
        {
            if (provider == null) {
                throw new ArgumentNullException("provider");
            }
            if (expression == null) {
                throw new ArgumentNullException("expression");
            }
            if (!typeof(IQueryable<T>).IsAssignableFrom(expression.Type)) {
                throw new ArgumentOutOfRangeException("expression");
            }
            this._provider = provider;
            this._expression = expression;
        }

        #region IEnumerable<T> 成员

        public IEnumerator<T> GetEnumerator()
        {
            return _provider.Execute<IEnumerator<T>, T>(this.Expression);
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return (this as IEnumerable<T>).GetEnumerator();
        }

        #endregion

        #region IQueryable 成员

        public Type ElementType
        {
            get { return typeof(T); }
        }

        public System.Linq.Expressions.Expression Expression
        {
            get { return this._expression; }
        }

        public IQueryProvider Provider
        {
            get { return _provider; }
        }

        #endregion

        public string QueryName
        {
            get
            {
                return _mappingTo ?? TypeMapper<T>.QueryName;
            }
        }

        public Dictionary<string, string> QueryPropertyFieldMap
        {
            get
            {
                return TypeMapper<T>.QueryPropertyFieldMap;
            }
        }
    }
}
